﻿using System;
using System.Configuration;
using System.Data;
using System.Data.OleDb;
using System.Data.OracleClient;
using System.Data.SqlClient;
using EIP.Common.Dapper.Extensions.Common;

namespace EIP.Common.Dapper.Extensions.DBUtility
{
    /// <summary>
    ///     数据库工厂
    /// </summary>
    public class DbFactory
    {
        /// <summary>
        ///     用于数据库类型的字符串枚举转换
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T DatabaseTypeEnumParse<T>(string value)
        {
            try
            {
                return CommonUtils.EnumParse<T>(value);
            }
            catch
            {
                throw new Exception("数据库类型\"" + value + "\"错误，请检查！");
            }
        }

        /// <summary>
        ///     根据配置文件中所配置的数据库类型
        ///     来获取命令参数中的参数符号oracle为":",sqlserver为"@"
        /// </summary>
        /// <returns></returns>
        public static string CreateDbParmCharacter()
        {
            string character;

            switch (DbType)
            {
                case DatabaseType.Sqlserver:
                    character = "@";
                    break;
                case DatabaseType.Oracle:
                    character = ":";
                    break;
                case DatabaseType.Access:
                    character = "@";
                    break;
                default:
                    throw new Exception("数据库类型目前不支持！");
            }

            return character;
        }

        /// <summary>
        ///     根据配置文件中所配置的数据库类型和传入的
        ///     数据库链接字符串来创建相应数据库连接对象
        /// </summary>
        /// <param name="connectionString"></param>
        /// <returns></returns>
        public static IDbConnection CreateDbConnection(string connectionString)
        {
            IDbConnection conn;
            switch (DbType)
            {
                case DatabaseType.Sqlserver:
                    conn = new SqlConnection(connectionString);
                    break;
                case DatabaseType.Oracle:
                    conn = new OracleConnection(connectionString);
                    break;
                case DatabaseType.Access:
                    conn = new OleDbConnection(connectionString);
                    break;
                default:
                    throw new Exception("数据库类型目前不支持！");
            }

            return conn;
        }

        /// <summary>
        ///     根据配置文件中所配置的数据库类型
        ///     来创建相应数据库命令对象
        /// </summary>
        /// <returns></returns>
        public static IDbCommand CreateDbCommand()
        {
            IDbCommand cmd;
            switch (DbType)
            {
                case DatabaseType.Sqlserver:
                    cmd = new SqlCommand();
                    break;
                case DatabaseType.Oracle:
                    cmd = new OracleCommand();
                    break;
                case DatabaseType.Access:
                    cmd = new OleDbCommand();
                    break;
                default:
                    throw new Exception("数据库类型目前不支持！");
            }

            return cmd;
        }

        /// <summary>
        ///     根据配置文件中所配置的数据库类型
        ///     来创建相应数据库适配器对象
        /// </summary>
        /// <returns></returns>
        public static IDbDataAdapter CreateDataAdapter()
        {
            IDbDataAdapter adapter;
            switch (DbType)
            {
                case DatabaseType.Sqlserver:
                    adapter = new SqlDataAdapter();
                    break;
                case DatabaseType.Oracle:
                    adapter = new OracleDataAdapter();
                    break;
                case DatabaseType.Access:
                    adapter = new OleDbDataAdapter();
                    break;
                default:
                    throw new Exception("数据库类型目前不支持！");
            }

            return adapter;
        }

        /// <summary>
        ///     根据配置文件中所配置的数据库类型
        ///     和传入的命令对象来创建相应数据库适配器对象
        /// </summary>
        /// <returns></returns>
        public static IDbDataAdapter CreateDataAdapter(IDbCommand cmd)
        {
            IDbDataAdapter adapter;
            switch (DbType)
            {
                case DatabaseType.Sqlserver:
                    adapter = new SqlDataAdapter((SqlCommand) cmd);
                    break;
                case DatabaseType.Oracle:
                    adapter = new OracleDataAdapter((OracleCommand) cmd);
                    break;
                case DatabaseType.Access:
                    adapter = new OleDbDataAdapter((OleDbCommand) cmd);
                    break;
                default:
                    throw new Exception("数据库类型目前不支持！");
            }

            return adapter;
        }

        /// <summary>
        ///     根据配置文件中所配置的数据库类型
        ///     来创建相应数据库的参数对象
        /// </summary>
        /// <returns></returns>
        public static IDbDataParameter CreateDbParameter()
        {
            IDbDataParameter param;
            switch (DbType)
            {
                case DatabaseType.Sqlserver:
                    param = new SqlParameter();
                    break;
                case DatabaseType.Oracle:
                    param = new OracleParameter();
                    break;
                case DatabaseType.Access:
                    param = new OleDbParameter();
                    break;
                default:
                    throw new Exception("数据库类型目前不支持！");
            }

            return param;
        }

        /// <summary>
        ///     根据配置文件中所配置的数据库类型
        ///     和传入的参数来创建相应数据库的参数数组对象
        /// </summary>
        /// <returns></returns>
        public static IDbDataParameter[] CreateDbParameters(int size)
        {
            var i = 0;
            IDbDataParameter[] param;
            switch (DbType)
            {
                case DatabaseType.Sqlserver:
                    param = new SqlParameter[size];
                    while (i < size)
                    {
                        param[i] = new SqlParameter();
                        i++;
                    }
                    break;
                case DatabaseType.Oracle:
                    param = new OracleParameter[size];
                    while (i < size)
                    {
                        param[i] = new OracleParameter();
                        i++;
                    }
                    break;
                case DatabaseType.Access:
                    param = new OleDbParameter[size];
                    while (i < size)
                    {
                        param[i] = new OleDbParameter();
                        i++;
                    }
                    break;
                default:
                    throw new Exception("数据库类型目前不支持！");
            }

            return param;
        }

        /// <summary>
        ///     根据配置文件中所配置的数据库类型
        ///     来创建相应数据库的事物对象
        /// </summary>
        /// <returns></returns>
        public static IDbTransaction CreateDbTransaction()
        {
            var conn = CreateDbConnection(ConnectionString);

            if (conn.State == ConnectionState.Closed)
            {
                conn.Open();
            }

            return conn.BeginTransaction();
        }

        //获取数据库类型
        private static readonly string StrDbType = CommonUtils.GetConfigValueByKey("dbType");
        //将数据库类型转换成枚举类型
        public static DatabaseType DbType = DatabaseTypeEnumParse<DatabaseType>(StrDbType);
        //获取数据库连接字符串
        public static string ConnectionString =CommonUtils.GetConfigValueByKey("connectionStrings");
    }
}